package ace.module.product.core.impl.service.impl;

import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.model.SaveContext;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.model.SaveListContext;
import ace.cmp.id.generator.api.LongIdGenerator;
import ace.module.common.api.model.input.TenantInput;
import ace.module.product.api.model.input.PmsProductSaveInput;
import ace.module.product.core.impl.dao.entity.PmsApplication;
import ace.module.product.core.impl.dao.entity.PmsCommonGallery;
import ace.module.product.core.impl.dao.entity.PmsCommonTag;
import ace.module.product.core.impl.dao.entity.PmsCommonVideo;
import ace.module.product.core.impl.dao.entity.PmsProduct;
import ace.module.product.core.impl.dao.entity.PmsProductCategoryRelation;
import ace.module.product.core.impl.dao.entity.PmsProductDetail;
import ace.module.product.core.impl.dao.entity.PmsProductStatistic;
import ace.module.product.core.impl.dao.model.bo.PmsProductAttributeSaveBo;
import ace.module.product.core.impl.dao.model.bo.PmsProductSaveContextBo;
import ace.module.product.core.impl.dao.model.bo.PmsProductSkuSaveListBo;
import ace.module.product.core.impl.manager.PmsApplicationManager;
import ace.module.product.core.impl.manager.PmsCommonGalleryManager;
import ace.module.product.core.impl.manager.PmsCommonTagManager;
import ace.module.product.core.impl.manager.PmsCommonVideoManager;
import ace.module.product.core.impl.manager.PmsProductAttributeManager;
import ace.module.product.core.impl.manager.PmsProductAttributeValueManager;
import ace.module.product.core.impl.manager.PmsProductCategoryRelationManager;
import ace.module.product.core.impl.manager.PmsProductDetailManager;
import ace.module.product.core.impl.manager.PmsProductManager;
import ace.module.product.core.impl.manager.PmsProductSkuAttributeValueManager;
import ace.module.product.core.impl.manager.PmsProductSkuManager;
import ace.module.product.core.impl.manager.PmsProductStatisticManager;
import ace.module.product.core.impl.manager.helper.PmsProductAttributeValueHelperMgr;
import ace.module.product.core.impl.service.PmsProductService;
import ace.module.product.core.impl.service.helper.PmsProductAttributeHelper;
import ace.module.product.core.impl.service.helper.PmsProductSkuHelper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * module init.
 *
 * @author Caspar
 */
@Slf4j
@AllArgsConstructor
@Component
public class PmsProductServiceImpl implements PmsProductService {

  private final LongIdGenerator idGenerator;
  private final PmsApplicationManager pmsApplicationManager;
  private final PmsProductManager pmsProductManager;
  private final PmsProductDetailManager pmsProductDetailManager;
  private final PmsProductAttributeManager pmsProductAttributeManager;
  private final PmsProductAttributeValueManager pmsProductAttributeValueManager;
  private final PmsProductSkuManager pmsProductSkuManager;
  private final PmsProductSkuAttributeValueManager pmsProductSkuAttributeValueManager;
  private final PmsProductCategoryRelationManager pmsProductCategoryRelationManager;
  private final PmsProductStatisticManager pmsProductStatisticManager;
  private final PmsCommonGalleryManager pmsCommonGalleryManager;
  private final PmsCommonVideoManager pmsCommonVideoManager;
  private final PmsCommonTagManager pmsCommonTagManager;
  private final PmsProductAttributeHelper pmsProductAttributeHelper;
  private final PmsProductAttributeValueHelperMgr pmsProductAttributeValueHelperMgr;
  private final PmsProductSkuHelper pmsProductSkuHelper;

  private Long save(PmsApplication pmsApplication, PmsProductSaveInput input) {

    SaveContext<PmsProduct> pmsProductSaveContext = pmsProductManager.assembleSaveContext(pmsApplication, input.getBase());

    SaveContext<PmsCommonGallery> pmsProductMainImageSaveContext = pmsCommonGalleryManager
        .assembleProductMainImageSaveContext(pmsProductSaveContext.getData().getPmsAppId(), pmsProductSaveContext.getData().getId(), input.getBase().getMainImgUrl());

    SaveListContext<PmsCommonGallery> pmsProductGalleriesSaveListContext = pmsCommonGalleryManager
        .assembleProductGalleriesSaveListContext(pmsProductSaveContext.getData().getPmsAppId(), pmsProductSaveContext.getData().getId(), input.getBase().getGalleries());

    SaveContext<PmsCommonVideo> pmsProductVideoSaveContext = pmsCommonVideoManager.assembleProductMainVideoSaveContext(pmsProductSaveContext.getData(), input.getBase().getMainVideoUrl());

    SaveListContext<PmsProductDetail> pmsProductDetailSaveListContext = pmsProductDetailManager.assembleProductSaveListContext(input.getDetails(), pmsProductSaveContext);

    PmsProductAttributeSaveBo pmsProductAttributeSaveBo = pmsProductAttributeHelper.assemblePmsProductAttributeSaveBo(input.getProductAttributes(), pmsProductSaveContext);

    PmsProductSkuSaveListBo pmsProductSkuSaveListBo = pmsProductSkuHelper.assemblePmsProductSkuSaveListBo(
        pmsProductSaveContext,
        pmsProductAttributeSaveBo,
        input.getSkus()
    );

    pmsProductSkuManager.checkValidSkuTotalCount(pmsProductAttributeSaveBo, input.getSkus().size());

    SaveListContext<PmsCommonTag> pmsProductTagSaveListContext = pmsCommonTagManager.assembleProductSaveListContext(pmsProductSaveContext.getData(), input.getTagIds());

    SaveContext<PmsProductCategoryRelation> pmsProductCategoryRelation = pmsProductCategoryRelationManager
        .assemblePmsProductCategoryRelationSaveContext(pmsProductSaveContext.getData(), input.getBase().getCategoryId());

    SaveContext<PmsProductStatistic> pmsProductStatisticSaveContext = pmsProductStatisticManager.assembleSaveContext(pmsProductSaveContext);

    PmsProductSaveContextBo context = PmsProductSaveContextBo.builder()
        .product(pmsProductSaveContext)
        .productCategoryRelation(pmsProductCategoryRelation)
        .productMainImage(pmsProductMainImageSaveContext)
        .productMainVideo(pmsProductVideoSaveContext)
        .productGalleries(pmsProductGalleriesSaveListContext)
        .productDetails(pmsProductDetailSaveListContext)
        .productStatistic(pmsProductStatisticSaveContext)
        .productAttributes(pmsProductAttributeSaveBo.getAttributes())
        .productAttributeValues(pmsProductAttributeSaveBo.getAttributeValues())
        .productSkus(pmsProductSkuSaveListBo.getProductSku())
        .productSkuAttributeValues(pmsProductSkuSaveListBo.getProductSkuAttributeValues())
        .productSkuMainImages(pmsProductSkuSaveListBo.getProductSkuMainImages())
        .productTags(pmsProductTagSaveListContext)
        .build();

    return pmsProductSaveContext.getData().getId();
  }


  @Override
  public Long add(TenantInput<PmsProductSaveInput> input) {
    return null;
  }
}